package com.gongj.rabbit.produce;

import com.gongj.rabbit.utils.RabbitMQUtil;
import com.rabbitmq.client.*;

import java.io.IOException;

/**
 * Return机制 与 异步confirm
 */
public class Return {

        public static void main(String[] args) throws IOException {
            Connection conn = RabbitMQUtil.createConn();
            Channel channel = conn.createChannel();
            String quequ = "queue-2";
            String exchange = "exchange-2";
            String key = "key-2222";
            //创建交换机
            channel.exchangeDeclare(exchange, BuiltinExchangeType.TOPIC, true);
            //创建队列
            channel.queueDeclare(quequ, true, false, false, null);
            //队列与交换机绑定
            //channel.queueBind(quequ, exchange, key);
            //开启消息确认机制
            channel.confirmSelect();
            channel.addConfirmListener(new ConfirmListener() {
                //参数一：deliveryTag： 消息的编号
                //参数二：multiple：是否批量confirm true 是
                public void handleAck(long deliveryTag, boolean multiple) throws IOException {
                    System.out.println("消息发送到交换机成功,deliveryTag: " + deliveryTag + ", multiple: " + multiple);
                }

                public void handleNack(long deliveryTag, boolean multiple) throws IOException {
                    System.out.println("消息发送到交换机失败, deliveryTag: " + deliveryTag + ", multiple: " + multiple);
                }
            });
            //Return机制
            channel.addReturnListener(new ReturnListener() {
                /*
                 * 参数1：响应code
                 * 参数2：响应文本
                 * 参数3：交换机名称
                 * 参数4：路由key
                 * 参数5：消息的基本属性集
                 * 参数6：消息内容
                 */
                public void handleReturn(int replyCode, String replyText,
                                         String exchange, String routingKey,
                                         AMQP.BasicProperties properties, byte[] body) throws IOException {
                    //此处便是执行Basic.Return之后回调的地方
                    //如果交换机发送消息到队列失败，则执行此方法
                    System.out.println("replyCode =" + replyCode);
                    System.out.println("replyText =" + replyText);
                    System.out.println("exchange =" + exchange);
                    System.out.println("routingKey =" + routingKey);
                    System.out.println("properties =" + properties);
                    System.out.println("body =" + new String(body));
                }
            });

            /**
             * 第三个参数：mandatory：当 mandatory 参数设为 true 时，
             * 交换器无法根据自身的类型和路由键找到一个符合条件的队列时，
             * 那么 RabbitMQ 会调用 Basic.Return 命令将消息返回给生产者。
             * 当 mandatory参数设置为 false 时，出现上述情形，则消息直接被丢弃。
             */
            String message = "发送路由key为 =" + key +"的消息";
            channel.basicPublish(exchange, key,false, null,message.getBytes());
            System.out.println("其他逻辑");
        }
}
